home *** CD-ROM | disk | FTP | other *** search
/ The Business Master (3rd Edition) / The Business Master (3rd Edition).iso / files / utilreen / txt2ps / psprint.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  10KB  |  299 lines

  1. /*+
  2.     Name:       psprint.c
  3.     Date:       26-Jan-1989
  4.     Author:     Kent J. Quirk
  5.                 Totel Systems, Inc.
  6.                 489 Groton Road
  7.                 Westford, MA  01886
  8.                 (508) 692-9535
  9.                 BIX and MCI Mail:  kquirk
  10.     
  11.     Abstract:   This program provides a way to list text files on a PostScript
  12.                 printer.  It works by enclosing and quoting each line of
  13.                 the file and sending it to the printer as a PostScript
  14.                         command.  Many parameters are variable.
  15.  
  16.     Usage:      This program is a filter; that is, it takes input from stdin
  17.                 and writes its output to stdout.  There are a number of
  18.                 switches supported (defaults in parentheses).
  19.                     
  20.                     -m - set left margin (in points) (24)
  21.                     -t - set top margin (in points) (24)
  22.                     -l - set leading (points between lines) (11.5)
  23.                     -p - set pointsize of font (10)
  24.                     -f - set font name (Courier)
  25.             -n - set number of lines per page (66)
  26.             -i - ignore form feeds
  27.                     -? - print a help message
  28.         
  29.                 All the defaults (except page length) are set in the file
  30.                 PSPRINT.PS, which must be in the same directory as this
  31.                 program.  If you don't use DOS 3.0 or later, it probably has 
  32.                 to be in the current directory.
  33.                 
  34.                 In fact, the file is not searched for by that name, but by
  35.                 the same name as the program and with the extension .PS.  
  36.                 If you need to rename this, you can do it; just rename the
  37.                 .PS file as well.
  38.                 
  39.                 PSPRINT pays attention to control-L characters as long as they
  40.                 occur as the first character on a line.  I've never seen a
  41.                 program that didn't print them there, so I think this is safe
  42.         (but it's lazy).
  43.            
  44.     History:    26-Jan-89 - Kent J. Quirk, Totel Systems, Inc.
  45.         Original Version
  46.         
  47.         3-3-89 - Tim Frost, Roundhill Computer Systems Limited
  48.         The program will now process file names (including wildcards
  49.         if linked with the C compiler wildcard function) if specified
  50.         after the flags on the command line.  If no file names are
  51.         present, it still uses standard input.    If filenames are
  52.         processed, it ignores standard input.  LINK WITH ALTERNATE
  53.         SETARGV (MSC) or WILDARGS (TC2) MODULE TO GET WILDCARD
  54.         SUPPORT ON COMMAND LINE.
  55.                                 
  56.         If the PSPOUT envirpnment variable is set, the program uses
  57.         its value as a file to write to instead of standard output. 
  58.         (e.g. "SET PSPOUT=LPT2").
  59.         
  60.         3-5-89 - kjq
  61.         Added -i (ignore form feeds) switch.  Cleaned up dofile() to
  62.         accomodate it.    Linked with setargv.obj and rereleased.
  63.     
  64.     Bugs:       It can't print sideways yet.  There are PostScript programs
  65.                 (see the Adobe book) which will take this output and print it
  66.                 in half-page form.
  67.                 
  68.         Form Feeds should be handled anywhere on a line.
  69.         
  70.         Tabs should be optionally expandable.
  71.                 
  72.                 It might be nice to emit a trailer that conforms with the 
  73.                 Adobe style spec defining fonts used and number of pages.
  74. -*/
  75.  
  76. #include <stdio.h>
  77. #include <io.h>
  78. #include <fcntl.h>
  79. #include <stdlib.h>
  80. #include <string.h>
  81.  
  82. #define BUFSIZE 250
  83.  
  84. int pagelen = 66;
  85. int ignoreff = 0;
  86. int filedone = 0;
  87.  
  88. /**** p s q u o t e ****
  89.     Abstract:   This routine takes a string and "quotes" it for PostScript.
  90.                 That is, it surrounds it in parens and escapes any character 
  91.                         less than a space, as well as parens and backslash.
  92.     Parameters: The input string
  93.     Returns:    A pointer to a PostScript version of the input string.
  94.     Comments:   The output string is limited to 250 characters.
  95.                 The output string is a static buf used on every call to
  96.                 this routine.  If you want to keep the string around,
  97.                 copy it to your own area or do a strdup() to duplicate it.
  98. ****************************/
  99. char *psquote(char *s)
  100. {
  101.     static char buf[BUFSIZE];
  102.     int i = 0;
  103.  
  104.     buf[i++] = '(';
  105.     for (; i<BUFSIZE-2; i++, s++)
  106.     {
  107.         if (*s)
  108.         {
  109.             if ((*s < ' ') || (*s > '\x7e'))
  110.             {
  111.                 sprintf(buf+i, "\\%3.3o", *s);
  112.                 i+=3;
  113.             }
  114.             else
  115.             {    
  116.                 switch (*s) 
  117.                 {
  118.                 case '(':
  119.                 case ')':
  120.                 case '\\':
  121.                     buf[i++] = '\\';            /* no break */
  122.                 default:
  123.                     buf[i] = *s;
  124.                 }
  125.             }
  126.         }
  127.         else
  128.             break;
  129.     }
  130.     if (i == 1)                 /* no characters added */
  131.         buf[i++] = ' ';         /* so add a space to satisfy show */
  132.     buf[i++] = ')';             /* then close it and terminate it */
  133.     buf[i++] = 0;
  134.     return(buf);
  135. }
  136.  
  137. /**** u s a g e ****
  138.     Prints a usage message to stderr and quits.
  139. ****************************/
  140. void usage(void)
  141. {
  142.     fprintf(stderr, "PSPRINT -[mtlpfn] [file ... ]\n");
  143.     fprintf(stderr, "This program reads each named file (or standard input, if\n");
  144.     fprintf(stderr, "no files specified) and sends it to the standard output\n");
  145.     fprintf(stderr, "(or to the file named in the PSPOUT environment variable,\n");
  146.     fprintf(stderr, "if defined) as a PostScript print file.  Options are:\n");
  147.     fprintf(stderr, " -m - set left margin (in points) (24)\n");
  148.     fprintf(stderr, " -t - set top margin (in points) (24)\n");
  149.     fprintf(stderr, " -l - set leading (points between lines) (11.5)\n");
  150.     fprintf(stderr, " -p - set pointsize of font (10)\n");
  151.     fprintf(stderr, " -f - set font name (Courier)\n");
  152.     fprintf(stderr, " -n - set number of lines per page (66)\n");
  153.     fprintf(stderr, " -i - ignore form feeds (deletes them)\n");
  154.     fprintf(stderr, " -? - print this message\n");
  155.     exit(1);
  156. }
  157.  
  158. /**** d o f i l e ****
  159.     Processes one input file.
  160. ****************************/
  161. void dofile(void)
  162. {
  163.     char buf[BUFSIZE];
  164.     char *bp;
  165.     int newpage = 0;
  166.     register int i;
  167.  
  168.     for (i=1; bp = gets(buf); i++)    /* for every line in input file */
  169.     {
  170.     if (*bp == '\x0C')         /* forced new page */
  171.     {
  172.         bp++;
  173.         if (!ignoreff)
  174.         newpage = 1;
  175.     }
  176.     else if ((filedone) || (i % pagelen == 0))   /* calculated new page */
  177.     {
  178.         filedone = 0;
  179.         newpage = 1;
  180.     }
  181.     
  182.     if (newpage)
  183.         {
  184.             printf("sp ");
  185.         i = 1;
  186.         newpage = 0;
  187.         }
  188.     printf("%s nl\n", psquote(bp));
  189.     }
  190. }
  191.  
  192. /**** m a i n ****
  193.     The main routine that does all the work.  Opens the PSPRINT.PS file,
  194.     emits its contents up to the %%EndProlog message, emits any changed
  195.     parameters, then finishes PSPRINT.PS.  Finally, it sends the quoted
  196.     input file.
  197. ****************************/
  198. main(int argc, char *argv[])
  199. {
  200.     char buf[BUFSIZE];
  201.     char *p;
  202.     FILE *f;
  203.     char * parg;
  204.     char * pspout;
  205.  
  206.     if ((pspout = getenv("PSPOUT")) != NULL)
  207.     {
  208.         int outdev;
  209.  
  210.         outdev = open(pspout,O_TEXT|O_WRONLY);
  211.         if (outdev < 0)
  212.         {
  213.             fprintf(stderr,"Unable to open output file %s",pspout);
  214.             exit(1);
  215.         }
  216.         dup2(outdev,1);
  217.     }
  218.  
  219.     if (argv[1][1] == '?')
  220.         usage();
  221.     if ((argc == 1) && (isatty(0)))  /* no args, stdin not redirected */
  222.         usage();
  223.  
  224.     strcpy(buf, argv[0]);
  225.     if ((p = strchr(buf, '.')) != NULL) 
  226.         *p = 0;
  227.     strcat(buf, ".ps");             /* open file with this name but .ps ext */
  228.  
  229.     if ((f = fopen(buf, "r")) == NULL)
  230.     {
  231.         fprintf(stderr, "Unable to open PostScript header file '%s'\n", 
  232.             buf);
  233.         return(1);
  234.     }
  235.  
  236.     while (fgets(buf, BUFSIZE, f) != NULL)              /* while more file */
  237.     {
  238.         if (strncmp(buf, "%%EndProlog", 10) == 0)       /* copy to EndProlog */
  239.         {
  240.             while ((parg = *++argv) != NULL)
  241.             {
  242.                 if (*parg == '-')
  243.                 {
  244.                     switch (*(parg + 1))
  245.                     {
  246.                     case 'm':
  247.                         printf("/lmarg %s def\n", parg+2);
  248.                         break;
  249.                     case 't':
  250.                         printf("/tmarg %s def\n", parg+2);
  251.                         break;
  252.                     case 'l':
  253.                         printf("/leading %s def\n", parg+2);
  254.                         break;
  255.                     case 'p':
  256.                         printf("/pointsize %s def\n", parg+2);
  257.                         break;
  258.                     case 'f':
  259.                         printf("/font /%s def\n", parg+2);
  260.                         break;
  261.                     case 'n':
  262.                         pagelen = atoi(parg+2);
  263.             break;
  264.             case 'i':
  265.             ignoreff = 1;
  266.             break;
  267.                     default:
  268.                         fprintf(stderr, "Don't know what to do with '%s'\n",
  269.                             parg);
  270.                         break;
  271.                     }
  272.                 }
  273.                 else break;
  274.             }
  275.         }
  276.         printf("%s", buf);
  277.     }
  278.     fclose(f);
  279.  
  280.     while ((parg = *argv++) != NULL)
  281.     {
  282.         int infile;
  283.  
  284.         infile = open(parg,O_TEXT|O_RDONLY);
  285.         if (infile < 0)
  286.         {
  287.             fprintf(stderr, "Unable to open input file %s\n",parg); 
  288.             exit(1);
  289.         }
  290.         dup2(infile,0);
  291.         dofile();
  292.         filedone++;
  293.     }
  294.  
  295.     if (!filedone) dofile();
  296.     printf("lp\n");           /* show the last page */
  297.     return(0);
  298. }
  299.